package com.sczmgk.hotline_pzh.httputils;

import android.app.Dialog;
import android.content.Context;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;
import com.linkrenhe.frame.http.Tools;
import com.sczmgk.hotline_pzh.DesJson.Base64;
import com.sczmgk.hotline_pzh.DesJson.Des3;
import com.sczmgk.hotline_pzh.DesJson.ResponseBean;
import com.sczmgk.hotline_pzh.DesJson.SessionKeyBean;
import com.sczmgk.hotline_pzh.MyApp;
import com.sczmgk.hotline_pzh.callback.CrashExceptionCallback;
import com.sczmgk.hotline_pzh.callback.HttpCallback;
import com.sczmgk.hotline_pzh.callback.HttpFailCallback;
import com.sczmgk.hotline_pzh.callback.OnPaseBaseJsonCallback;
import com.sczmgk.hotline_pzh.constants.Constants;
import com.sczmgk.hotline_pzh.dialog.DialogFactory;
import com.sczmgk.hotline_pzh.entity.BaseEntity;
import com.sczmgk.hotline_pzh.entity.BaseEntity.MyError;
import com.sczmgk.hotline_pzh.sp.CacheUtils;
import com.sczmgk.hotline_pzh.utils.CommonUtils;
import com.sczmgk.hotline_pzh.utils.MyLog;
import com.sczmgk.hotline_pzh.utils.MyToast;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.entity.StringEntity;
import org.json.JSONObject;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;

/**
 * 自定义封装Http请求
 */
public class MyHttp {

    private static final String TAG = MyHttp.class.getSimpleName();
    /**
     * 服务请求的队列
     */
   private static  Map<String,Boolean> requestQueue = new HashMap<String,Boolean>();
    /**
     * 返回的结果没有错误
     */
    public static final int NO_ERROR = 0;
    public static final int GET = 1;
    public static final int POST = 2;
    public static final int PUT = 3;
    public static final int HEAD = 4;
    public static final int MOVE = 5;
    public static final int COPY = 6;
    public static final int DELETE = 7;
    public static final int OPTIONS = 8;
    public static final int TRACE = 9;
    public static final int CONNECT = 10;
    public static final int UPLOAD_FILE = 11;
    public static final int DOWNLOAD_FILE = 12;
    private static boolean isCached;

    public static void sendGET(String url, final HttpCallback callback) {

        HttpUtils httpUtils = new HttpUtils();
        httpUtils.send(HttpMethod.GET, url, new RequestCallBack<String>() {

            @Override
            public void onSuccess(ResponseInfo<String> responseInfo) {
                MyLog.i(TAG, "请求成功：" + responseInfo.result);
                if (callback != null) {
                    callback.onSuccess(responseInfo.result);
                }
            }

            @Override
            public void onFailure(HttpException error, String msg) {
                if (callback != null) {
                    callback.onFailure(error, msg);
                }
                MyLog.e(TAG, "请求失败  errot = " + error.getMessage() + "   msg = " + msg);
            }

            @Override
            public void onException() {

            }
        });
    }

    /**
     * 请求数据001
     *
     * @param url                  请求url
     * @param filePath             文件路径
     * @param dataMaps             请求数据
     * @param requestType          请求类型
     * @param context
     * @param isCache              是否为缓存
     * @param cacheKey             缓存Key
     * @param areaCode             区域码
     * @param loadDialog           加载的进度条
     * @param paseBaseJsonCallback 解析完成的回调接口
     * @param failCallback         请求失败的回调
     * @param crashExceptionCallback    上传App异常的回调
     */
    public static void requestByCache1(final String url, final String filePath, final Map<String, Object> dataMaps, final int requestType,
                                       final Context context, final boolean isCache, final String cacheKey, final String areaCode, final Dialog loadDialog,
                                       final OnPaseBaseJsonCallback paseBaseJsonCallback, final HttpFailCallback failCallback, final CrashExceptionCallback crashExceptionCallback) {
        //缓存数据的key
        final String dataKey = url + areaCode + cacheKey;
        final String sessionKey = url + areaCode + cacheKey + "sessionKey";
        //1.取出缓存
        String cacheJson = CacheUtils.getStringData(context, dataKey, null);
        if (cacheJson != null) {
            //解析缓存需要缓存的sessionkey
            paserBaseJson(cacheJson, paseBaseJsonCallback, true, CacheUtils.getStringData(context, sessionKey, ""));
        }
        if (!CommonUtils.isNetworkAvailable(context)) {
            try {
                MyToast.show(context, "请检查网络!");
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(failCallback != null)
            failCallback.onServiceErrorCallback();
            return;
        }
        requestQueue.put(url,true);
        if (loadDialog != null) {
            try {
                loadDialog.show();//打开进度条
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //2.请求数据
        final String rawData = MyHttp.getDataJson(dataMaps);
        //
        requestByCheckSessionkey(context,url,false,isCache,filePath,dataMaps,rawData,dataKey,sessionKey,requestType,
                loadDialog,paseBaseJsonCallback,failCallback, crashExceptionCallback);

    }

    /**
     * 请求数据001
     *
     * @param url                  请求url
     * @param filePath             文件路径
     * @param dataMaps             请求数据
     * @param requestType          请求类型
     * @param context
     * @param isCache              是否为缓存
     * @param cacheKey             缓存Key
     * @param areaCode             区域码
     * @param loadDialog           加载的进度条
     * @param paseBaseJsonCallback 解析完成的回调接口
     * @param failCallback         请求失败的回调
     * @param crashExceptionCallback    上传App异常的回调
     */
    public static void requestByCache(final String url, final String filePath, final Map<String, Object> dataMaps, final int requestType,
                                      final Context context, final boolean isCache, final String cacheKey, final String areaCode, final Dialog loadDialog,
                                      final OnPaseBaseJsonCallback paseBaseJsonCallback, final HttpFailCallback failCallback, final CrashExceptionCallback crashExceptionCallback) {
        //缓存数据的key
        final String dataKey = url + areaCode + cacheKey;
        final String sessionKey = url + areaCode + cacheKey + "sessionKey";
        //1.取出缓存
        String cacheJson = CacheUtils.getStringData(context, dataKey, null);
        if (cacheJson != null) {
            //解析缓存需要缓存的sessionkey
            paserBaseJson(cacheJson, paseBaseJsonCallback, true, CacheUtils.getStringData(context, sessionKey, ""));
        }
        if (!CommonUtils.isNetworkAvailable(context)) {

            try {
                MyToast.show(context, "请检查网络!");
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(failCallback != null)
            failCallback.onServiceErrorCallback();
            return;
        }
        boolean isDisconnection = CacheUtils.getBooleanData(context, Constants.IS_DISCONNECTION_NETWORK, false);
        MyLog.d(TAG,"取出缓存断开的状态： "+isDisconnection);
        if(isDisconnection){

            MyLog.e(TAG,"网络有断开，调用单点方法----------");
            CommonUtils.reportImei(context);
        }
        requestQueue.put(url,true);
         //2.请求数据
        final String rawData = MyHttp.getDataJson(dataMaps);
        //
        requestByCheckSessionkey(context,url,false,isCache,filePath,dataMaps,rawData,dataKey,sessionKey,requestType,
                loadDialog,paseBaseJsonCallback,failCallback, crashExceptionCallback);

    }

    /**
     * 根据传入的isSessionInvalid请求数据 
     * @param context
     * @param url
     * @param isSessionInvalid  1. 默认传false(服务端没回调session过期的情况,GET请求不能返回)
     * @param isCache
     * @param filePath
     * @param dataMaps
     * @param rawData
     * @param dataKey
     * @param sessionKey
     * @param requestType
     * @param loadDialog
     * @param paseBaseJsonCallback
     * @param failCallback
     * @param crashExceptionCallback
     */
    private static void requestByCheckSessionkey(final Context context, final String url, final boolean isSessionInvalid,
                                                 final boolean isCache, final String filePath, final Map<String, Object> dataMaps,
                                                 final String rawData, final String dataKey, final String sessionKey, final int requestType,
                                                 final Dialog loadDialog, final OnPaseBaseJsonCallback paseBaseJsonCallback,
                                                 final HttpFailCallback failCallback, final CrashExceptionCallback crashExceptionCallback){


        if (isSessionInvalid){//密钥过期或错误，请type
            MyApp.type = 0;
        }
        requestBySessionKey(url, filePath, MyHttp.getRequestJson(rawData, false), dataMaps, new HttpCallback() {

            @Override
            public void onSuccess(String result) {
                try {
                    if (loadDialog != null) {
                        DialogFactory.dismissLoadingDialog(loadDialog);
                    }
                } catch (Exception e) {
                    MyLog.e(TAG, "关闭loading 对话框错误");
                }
                if (isCache) {
                    MyLog.e(TAG, "----需要缓存-----：   ");
//								MyLog.e(TAG,"----需要缓存-----：   "+result);
                    //缓存数据
                    CacheUtils.cacheStringData(context, dataKey, result);
                    //缓存sessionkey
                    CacheUtils.cacheStringData(context, sessionKey, MyApp.sessionKey);
                } else {
                    MyLog.d(TAG, "----不需要缓存-----：   ");
//								MyLog.d(TAG,"----不需要缓存-----：   "+result);
                }

                paserBaseJson(context,url,filePath,dataMaps,rawData,dataKey,sessionKey,requestType,
                        loadDialog,result, paseBaseJsonCallback,failCallback, crashExceptionCallback,false, MyApp.sessionKey);
            }

            @Override
            public void onFailure(HttpException error, String msg) {
                if (isSessionInvalid) {//这已是密钥过期或错误后的第二次请求，不做任何处理，回调失败
                    if (failCallback != null) {
                        failCallback.onServiceErrorCallback();
                    }
                    try {
                        if (loadDialog != null) {
                            DialogFactory.dismissLoadingDialog(loadDialog);
                        }
                    } catch (Exception e) {
                        MyLog.e(TAG, "关闭loading 对话框错误");
                    }
                    //
//                    DialogFactory.warningDialog(context, context.getResources().getString(R.string.dialog_tip),
//                            context.getResources().getString(R.string.dialog_network_error),
//                            context.getResources().getString(R.string.sure), new View.OnClickListener() {
//
//                                @Override
//                                public void onClick(View v) {
//                                    //点击重新连接
//                                }
//                            });
                } else {//第二次请求()
                    if (requestType == GET) {
                        MyLog.d(TAG, "------------（验证错误，没有返回密钥过期,因是Get，不能返回）---------  重新请求一次");
                        requestByCheckSessionkey(context, url, true, isCache, filePath, dataMaps, rawData, dataKey, sessionKey,
                                requestType, loadDialog, paseBaseJsonCallback, failCallback, crashExceptionCallback);
                    }
                }

            }

            @Override
            public void onException() {
                if (loadDialog != null) {
                    DialogFactory.dismissLoadingDialog(loadDialog);
                }
                if (crashExceptionCallback != null) {
                    crashExceptionCallback.onCrashExceptionCallback();
                }

            }
        }, rawData, requestType);
    }
    /**
     * 请求数据   上传图片
     *
     * @param url                  url
     * @param filePath             文件路径
     * @param dataMaps             请求的集合
     * @param requestType          请求类型  GET POST PUT  DELETE
     * @param context
     * @param isCache              是否缓存数据
     * @param loadDialog           提示的对话框
     * @param paseBaseJsonCallback 解析完成的回调接口
     */

    public static void requestByUploadPic(final String url, String filePath, Map<String, Object> dataMaps, int requestType,
                                          final Context context, final boolean isCache, final Dialog loadDialog, final OnPaseBaseJsonCallback paseBaseJsonCallback) {
        requestByCache(url, filePath, dataMaps, requestType, context, isCache, null,null, loadDialog, paseBaseJsonCallback, null,null);
    }

    /**
     * 请求数据,用于投诉上传图片用，需要返回服务器错误的回调
     *
     * @param url                  url
     * @param filePath             文件路径
     * @param dataMaps             请求的集合
     * @param requestType          请求类型  GET POST PUT  DELETE
     * @param context
     * @param isCache              是否缓存数据
     * @param loadDialog           提示的对话框
     * @param paseBaseJsonCallback 解析完成的回调接口
     * @param failCallback         服务器错误的回调
     */

    public static void requestByUploadFile(final String url, String filePath, Map<String, Object> dataMaps, int requestType,
                               final Context context, final boolean isCache, final Dialog loadDialog, final OnPaseBaseJsonCallback paseBaseJsonCallback, HttpFailCallback failCallback) {
        requestByCache(url, filePath, dataMaps, requestType, context, isCache, null,null, loadDialog, paseBaseJsonCallback, failCallback,null);
    }
    /**
     * 请求数据（上传App异常）
     *
     * @param url               url
     * @param dataMaps          请求的集合
     * @param requestType       请求类型  GET POST PUT  DELETE
     * @param context
     * @param crashExceptionCallback 上传App异常的回调
     */

    public static void requestByUploadAppException(final String url, Map<String, Object> dataMaps, int requestType, final Context context, CrashExceptionCallback crashExceptionCallback) {

        requestByCache(url, null, dataMaps, requestType, context, false, null, null, null,null, null, crashExceptionCallback);
    }


    /**
     * 请求数据（通用，没有文件路径,没有下拉刷新，上拉加载）
     *
     * @param url                  url
     * @param dataMaps             请求的集合
     * @param requestType          请求类型  GET POST PUT  DELETE
     * @param context
     * @param isCache              是否缓存数据
     * @param loadDialog           提示的对话框
     * @param paseBaseJsonCallback 解析完成的回调接口
     */

    public static void requestByReportImei(final String url, Map<String, Object> dataMaps, int requestType, final Context context,
                                       final boolean isCache, final Dialog loadDialog, final OnPaseBaseJsonCallback paseBaseJsonCallback) {
        requestByCache1(url, null, dataMaps, requestType, context, isCache, null,null, loadDialog, paseBaseJsonCallback, null,null);
    }
    /**
     * 请求数据（通用，没有文件路径,没有下拉刷新，上拉加载）
     *
     * @param url                  url
     * @param dataMaps             请求的集合
     * @param requestType          请求类型  GET POST PUT  DELETE
     * @param context
     * @param isCache              是否缓存数据
     * @param loadDialog           提示的对话框
     * @param paseBaseJsonCallback 解析完成的回调接口
     */

    public static void requestByCommon(final String url, Map<String, Object> dataMaps, int requestType, final Context context,
                               final boolean isCache, final Dialog loadDialog, final OnPaseBaseJsonCallback paseBaseJsonCallback) {
        requestByCache(url, null, dataMaps, requestType, context, isCache, null,null, loadDialog, paseBaseJsonCallback, null,null);
    }

    /**
     * 请求数据（没有文件路径, 有下拉刷新，上拉加载功能，请求失败后需要回调）
     *
     * @param url                  url
     * @param dataMaps             请求的集合
     * @param requestType          请求类型  GET POST PUT  DELETE
     * @param context
     * @param isCache              是否缓存数据
     * @param loadDialog           提示的对话框
     * @param paseBaseJsonCallback 解析完成的回调接口
     */

    public static void requestByFailCallback(final String url, Map<String, Object> dataMaps, int requestType, final Context context,
                               final boolean isCache, final Dialog loadDialog, final OnPaseBaseJsonCallback paseBaseJsonCallback, HttpFailCallback failCallback) {
        requestByCache(url, null, dataMaps, requestType, context, isCache, null, null,loadDialog, paseBaseJsonCallback, failCallback,null);
    }

    /**
     * 请求网络数据 1.先判断sessionkey是否过期(或是否取到了sessionkey)，如过期或没有sessionkey则申请sessionkey
     *             2.用申请到的sessionkey加密后重新请求
     *
     * @param url
     * @param filePath  文件路径
     * @param requestString 请求的字符串
     * @param dataMaps
     * @param httpCallback
     * @param jsonRawData       data原始数据
     * @param requestType
     */

    private static void requestBySessionKey(final String url, final String filePath,
                                    final String requestString, final Map<String, Object> dataMaps,
                                    final HttpCallback httpCallback, final String jsonRawData, final int requestType) {

        if (MyApp.type == 0) {// 没有取得密钥
            MyLog.i(TAG, "没有会话密钥，去取密钥");
            getSessionKey(new onGetSessionKeyCallback() {
                @Override
                public void onGetSessionKey(String sessionKey) {
                    MyLog.d(TAG, "----取密钥回调了，发起正常 请求");
                    String requstStr = "";
                    if (dataMaps != null) {
                        String rawData = MyHttp.getDataJson(dataMaps);
                        MyLog.e(TAG, "请求的原数据：" + rawData);
                        requstStr = MyHttp.getRequestJson(rawData, false);
                    } else {
                        requstStr =  MyHttp.getRequestJson(jsonRawData, false);
                    }
                    sendHttpRequest(url, filePath, requstStr, dataMaps, httpCallback,requestType);
                }

                @Override
                public void onGetSessionKeyError(String msg) {
                    MyLog.e(TAG, "取密钥失败");
                    httpCallback.onFailure(new HttpException(), msg);//没有处理
                }
            });
        } else {
            MyLog.d(TAG, "已取得密钥，发起正常请求");
            MyLog.e(TAG, "请求的原数据：" + jsonRawData);
            sendHttpRequest(url, filePath, requestString, dataMaps, httpCallback,requestType);

        }
    }

    /**
     * 发送http请求
     *
     * @param url
     * @param requestJson  序列化的Json字符串
     * @param filePath     上传文件的路径
     * @param httpCallback
     * @param requestType
     */
    private static void sendHttpRequest(String url, String filePath, String requestJson,
                                        final Map<String, Object> dataMaps, final HttpCallback httpCallback, int requestType) {
//		HttpUtils httpUtils = new HttpUtils();
        HttpUtils httpUtils = new HttpUtils(15000);
        RequestParams params = new RequestParams();
        httpUtils.configDefaultHttpCacheExpiry(0);
        params.setHeader("Cache-Control", "no-cache");
        params.setHeader("Pragrma", "no-cache");
        params.setHeader("expires", "0");
//		params.setHeader("Content-Type", "application/json");//增加
        String type = "";
        switch (requestType) {
            case POST:
                type = "POST";
                break;
            case GET:
                type = "GET";
                break;
            case PUT:
                type = "PUT";
                break;
            case DELETE:
                type = "DELETE";
                break;
            case UPLOAD_FILE:
                type = "UPLOAD_FILE";
                break;
            case DOWNLOAD_FILE:
                type = "DOWNLOAD_FILE";
                break;
            default:
                break;
        }
        switch (requestType) {
            case GET:
                MyLog.d(TAG, type + "请求的URL: " + url);
                params.addHeader("Authorization", "Bearer " + MyApp.token);
                MyLog.i(TAG, "Authorization  ---value:  " + "Bearer " + MyApp.token);
                MyLog.d(TAG, type + "请求的token:   " + MyApp.token);
                StringBuilder sb = new StringBuilder();
                for (Entry<String, Object> entrySet : dataMaps.entrySet()) {
                    sb.append(entrySet.getKey());
                    sb.append("=");
                    sb.append(entrySet.getValue());
                    sb.append("&");
                }
                String requestStr = sb.toString();
                requestStr = requestStr.substring(0, requestStr.length() - 1);
                url = url + requestStr;
                MyLog.i(TAG, type + "请求的字符串： " + url);
                httpUtils.send(HttpMethod.GET, url, params,
                        new RequestCallBack<String>() {
                            @Override
                            public void onSuccess(ResponseInfo<String> responseInfo) {
//							MyLog.i(TAG, "请求成功：" + responseInfo.result);
                                if (httpCallback != null) {
                                    httpCallback.onSuccess(responseInfo.result);
                                }
                            }

                            @Override
                            public void onFailure(HttpException error, String msg) {
                                if (httpCallback != null) {
                                    httpCallback.onFailure(error, msg);
                                }
                                MyLog.e(TAG, "请求失败  error = " + error.getMessage() + "   msg = " + msg);

                            }

                            @Override
                            public void onException() {
                                if (httpCallback != null) {
                                    httpCallback.onException();
                                }

                            }
                        });
                break;
            case POST:

                setParams(params, requestJson);
                MyLog.d(TAG, type + "请求的URL: " + url);
                MyLog.i(TAG, type + "请求的json串： " + requestJson);
                httpUtils.send(HttpMethod.POST, url, params,
                        new RequestCallBack<String>() {
                            @Override
                            public void onSuccess(ResponseInfo<String> responseInfo) {
                                MyLog.i(TAG, "请求成功：" + responseInfo.result);
                                if (httpCallback != null) {
                                    httpCallback.onSuccess(responseInfo.result);
                                }
                            }

                            @Override
                            public void onFailure(HttpException error, String msg) {
                                if (httpCallback != null) {
                                    httpCallback.onFailure(error, msg);
                                }
                                MyLog.e(TAG, "请求失败  error = " + error.getMessage() + "   msg = " + msg);
                            }

                            @Override
                            public void onException() {
                                if (httpCallback != null) {
                                    httpCallback.onException();
                                }

                            }
                        });
                break;
            case PUT:

                setParams(params, requestJson);
                MyLog.d(TAG, type + "请求的URL: " + url);
                MyLog.i(TAG, type + "请求的json串： " + requestJson);
                httpUtils.send(HttpMethod.PUT, url, params,
                        new RequestCallBack<String>() {
                            @Override
                            public void onSuccess(ResponseInfo<String> responseInfo) {
                                MyLog.i(TAG, "请求成功：" + responseInfo.result);
                                if (httpCallback != null) {
                                    httpCallback.onSuccess(responseInfo.result);
                                }
                            }

                            @Override
                            public void onFailure(HttpException error, String msg) {
                                if (httpCallback != null) {
                                    httpCallback.onFailure(error, msg);
                                }
                                MyLog.e(TAG, "请求失败  error = " + error.getMessage() + "   msg = " + msg);
                            }

                            @Override
                            public void onException() {
                                if (httpCallback != null) {
                                    httpCallback.onException();
                                }
                            }
                        });
                break;

            case DELETE:
                params.addHeader("Authorization", "Bearer " + MyApp.token);
                MyLog.d(TAG, type + "请求的URL: " + url);
                MyLog.i(TAG, type + "请求的json串： " + requestJson);
                StringBuilder sb1 = new StringBuilder();
                for (Entry<String, Object> entrySet : dataMaps.entrySet()) {
                    sb1.append(entrySet.getKey());
                    sb1.append("=");
                    sb1.append(entrySet.getValue());
                    sb1.append("&");
                }
                String requestStr1 = sb1.toString();
                requestStr = requestStr1.substring(0, requestStr1.length() - 1);
                url = url + requestStr;

                MyLog.i(TAG, "DELETE请求的字符串： " + url);
                httpUtils.send(HttpMethod.DELETE, url, params,
                        new RequestCallBack<String>() {
                            @Override
                            public void onSuccess(ResponseInfo<String> responseInfo) {
                                MyLog.i(TAG, "请求成功：" + responseInfo.result);
                                if (httpCallback != null) {
                                    httpCallback.onSuccess(responseInfo.result);
                                }
                            }

                            @Override
                            public void onFailure(HttpException error, String msg) {
                                if (httpCallback != null) {
                                    httpCallback.onFailure(error, msg);
                                }
                                MyLog.e(TAG, "请求失败  error = " + error.getMessage() + "   msg = " + msg);
                            }

                            @Override
                            public void onException() {
                                if (httpCallback != null) {
                                    httpCallback.onException();
                                }
                            }
                        });
                break;
            case UPLOAD_FILE:
                //1.拼装url
                String encodeJson = null;
                try {
                    encodeJson = Base64.encodeToString(
                            requestJson.getBytes("utf-8"), Base64.NO_WRAP).trim();// 自定义Base64lNo_WRAP是设置base64字符串里没有换行符
                } catch (Exception e) {
                    MyLog.e(TAG, "上传文件 的Base64加密错误!");
                }
                url = url + "filetypekey=" + encodeJson;//拼装的文件说明信息

                MyLog.i(TAG, type + "请求的字符串： " + url + "   filePath: " + filePath);
                params.addBodyParameter("file", new File(filePath));
                httpUtils.send(HttpMethod.POST, url, params,
                        new RequestCallBack<String>() {
                            @Override
                            public void onSuccess(ResponseInfo<String> responseInfo) {
                                MyLog.i(TAG, "请求成功：" + responseInfo.result);
                                if (httpCallback != null) {
                                    httpCallback.onSuccess(responseInfo.result);
                                }
                            }

                            @Override
                            public void onFailure(HttpException error, String msg) {
                                if (httpCallback != null) {
                                    httpCallback.onFailure(error, msg);
                                }
                                MyLog.e(TAG, "请求失败  error = " + error.getMessage() + "   msg = " + msg);
                            }

                            @Override
                            public void onException() {
                                if (httpCallback != null) {
                                    httpCallback.onException();
                                }
                            }
                        });
                break;
            case DOWNLOAD_FILE:

                break;
            default:
                break;
        }
    }

    /**
     * 下载文件 的方法
     *
     * @param url
     * @param target   存储位置
     * @param callback
     */
    public static void downloadFile(String url, String target, RequestCallBack<File> callback) {
        MyLog.d(TAG,"下载图片的URL: "+url + "    目标路径: "+target);
        HttpUtils httpUtils = new HttpUtils();
        httpUtils.download(url, target, callback);
    }


    /**
     * 请求参数为json（非Map）
     * @param url
     * @param jsonStr
     * @param requestType
     * @param context
     * @param paseBaseJsonCallback
     * @param failCallback
     */
    public static void requestFromJson(String url, String jsonStr, int requestType, Context context, OnPaseBaseJsonCallback paseBaseJsonCallback, final HttpFailCallback failCallback){
        requestByCheckSessionkey(context,url,false,false,null,null,jsonStr,"no","no",requestType,
                null,paseBaseJsonCallback,failCallback, null);
    }
    /**
     * 验证正常请求MD5值
     *
     * @param result
     * @return
     */
    private static boolean verificationMD5(String result) {
        Gson gson = new Gson();
        ResponseBean response = gson.fromJson(result, ResponseBean.class);
        // 取到加密的data
        String encodeSessionKey = response.data;
        // 取出解密后的data原数据,用会话密钥
        String rawData = Des3.des3DecodeECB(MyApp.sessionKey, encodeSessionKey);
        // MD5 data原数据
        String dataMD5 = MyHttp.getVerify(rawData);
        // 对比服务器传过来的原数据
        if (!dataMD5.equals(response.verify)) {
            MyLog.e(TAG, "data MD5 验证错误 ！");
            return false;
        } else {
            return true;
        }
    }

    /**
     * 解密data
     *
     * @param result 加密的data
     * @return 还原后的0json串
     */
    private static String getResultRawData(String result) {
        Gson gson = new Gson();
        ResponseBean response = gson.fromJson(result, ResponseBean.class);
        // 取到加密的data
        String encodeSessionKey = response.data;
        // 取出解密后的data原数据,用会话密钥
        String rawData = Des3.des3DecodeECB(MyApp.sessionKey, encodeSessionKey);
        return rawData;
    }

    /**
     * 取得正常请求的解密json原串
     *
     * @param dataEncodeStr
     * @return
     */
    private static String getDataRaw(String dataEncodeStr) {

        String rawData = Des3.des3DecodeECB(MyApp.sessionKey, dataEncodeStr);
        return rawData;
    }

    /**
     * 取得缓存的解密json原串
     *
     * @param dataEncodeStr
     * @param cacheSessionKey 缓存的密钥
     * @return 返回缓存的Json
     */
    private static String getCacheDataRaw(String dataEncodeStr, String cacheSessionKey) {
        String rawData = Des3.des3DecodeECB(cacheSessionKey, dataEncodeStr);
        if(Tools.isEmpty(rawData)){
            return "";
        }
        return rawData.toString();
    }

    // ////////////////////处理json部分/////////////////////////////////

    /**
     * 生成请求的Data原数据
     *
     * @param dataMaps 数据集合
     * @return json字符串
     */
    private static String getDataJson(Map<String, Object> dataMaps) {
        String result = "";
        JSONObject param = new JSONObject();
        try {
            for (Entry<String, Object> entry : dataMaps.entrySet()) {
                if (entry.getKey().equals("file")) {
                    param.put("file", new File((String) entry.getValue()));

                }
                {
                    param.put(entry.getKey(), entry.getValue());
                }
            }
            result = param.toString();

        } catch (Exception e) {
            MyLog.e(TAG, "生成请求Data的json原字符串 错误！！");
        }
        return result;
    }

    /**
     * 生成获取会话密钥data原数据
     *
     * @return 未加密的json字符串
     */
    private static String getSessionKeyDataJson() {
        String result = "";
        String imei = MyApp.imei;
        JSONObject param = new JSONObject();
        try {
            param.put("imei", imei);
            String randomCode = getRandomCode();
            MyApp.randomCode = randomCode;
            param.put("randomcode", randomCode);
            result = param.toString();
        } catch (Exception e) {
            MyLog.e(TAG, "生成取密钥的data原字符串错误");
        }
        return result;
    }

    /**
     * 取得请求数据的公共方法(1.context 2.加密后的data )
     *
     * @param data            未加密的Data数据
     * @param isGetSessionKey 是否为取会话密钥
     * @return json原数据
     */
    private static String getRequestJson(String data, boolean isGetSessionKey) {
        String result = "";
        int type = MyApp.type;
        String sessionKey;
        if (isGetSessionKey) {
            sessionKey = Constants.SERVICE_PUBLIC_KEY;
        } else {
            sessionKey = MyApp.sessionKey;
        }
        JSONObject param = new JSONObject();
        try {
            JSONObject context = getContextJson();
//            MyLog.d(TAG, "请求的 context :  " + context);
            param.put("context", context);
            MyLog.d(TAG, "未加密的data:  " + data);
            String encedeData = Des3.des3EncodeECB(sessionKey, data);
//            MyLog.i(TAG, "加密后的data:  " + encedeData);
            param.put("data", encedeData);
            param.put("verify", getVerify(data));
            param.put("type", type);
            result = param.toString();
        } catch (Exception e) {
            MyLog.e(TAG, "生成请求的json错误");
        }
        return result;
    }

    /**
     * 取得Context的数据
     *
     * @return context 返回 json 对象
     */
    private static JSONObject getContextJson() {
        String imei = MyApp.imei;
        String imsi = MyApp.imsi;
        int userid = MyApp.loginUserUid;
        JSONObject result = null;
        JSONObject param = new JSONObject();
        try {
            param.put("imei", imei);
            param.put("imsi", imsi);
            param.put("userid", ((userid == 0 || userid == -1) ? 0 : userid));
            result = param;
        } catch (Exception e) {
            MyLog.e(TAG, " 生成  context 错误 ！");
        }
        return result;
    }

    /**
     * 判断文字是否为空
     *
     * @param value
     * @return
     */
    public static boolean isEmpty(String value) {
        if (value == null || value.length() == 0 || "null".equals(value)) {
            return true;
        } else
            return false;
    }

    /**
     * 生成24位数字的随机数作为id
     *
     * @return 24位的随机码： 5d2fd5564155414564212sa
     */
    public static String getRandomCode() {
        String uuid = UUID.randomUUID().toString();
        uuid = uuid.replace("-", "");
        return uuid.substring(0, 24);
    }

    /**
     * 取得会话密钥 1.网络请求会话密钥 2.回调获取成功 3.开启定时器
     *
     * @param getSessionKeyCallback 取得密钥后的回调
     */
    private static void getSessionKey(final onGetSessionKeyCallback getSessionKeyCallback) {
        String data = getSessionKeyDataJson();
        String requestJson = getRequestJson(data, true);
        MyHttp.sendHttpRequest(Constants.BASE_URL+Constants.POST_SESSIONKEYS_URL, null, requestJson,
                null, new HttpCallback() {
                    @Override
                    public void onSuccess(String result) {
                        Gson gson = new Gson();
                        ResponseBean response = null;
                        try {
                            response = gson.fromJson(result, ResponseBean.class);

                        } catch (Exception e) {
                            MyLog.e(TAG, "取会话空密钥返回的Jso解析错误！");
                        }
                        if (response == null) {
                            return;
                        }
                        // 取到加密的data
                        String encodeSessionKey = response.data;
                        // 取出解密后的data原数据,用随机码解密
                        String rawData = Des3.des3DecodeECB(MyApp.randomCode, encodeSessionKey);
                        // MD5 data原数据
                        String dataMD5 = getVerify(rawData);
                        // 对比服务器传过来的原数据
                        if (!dataMD5.equals(response.verify)) {
                            MyLog.e(TAG, "data MD5 验证错误 ！");
                            return;
                        }
                        Gson gsonSessionKey = new Gson();
                        SessionKeyBean sessionKeyBean = gsonSessionKey.fromJson(rawData, SessionKeyBean.class);
                        String sessionKey = sessionKeyBean.sessionpwd;
                        String token = sessionKeyBean.token;
                        MyLog.d(TAG, "取到了会话密钥：" + sessionKey);
                        // 存入会话密钥
                        MyApp.sessionKey = sessionKey;
                        MyApp.token = token;
                        // 2.将type设置成 1
                        MyApp.type = 1;
                        if (getSessionKeyCallback != null) {
                            getSessionKeyCallback.onGetSessionKey(sessionKey);
                        }
                        String exptime = sessionKeyBean.exptime;
                        MyLog.d(TAG,"密钥过期时间："+exptime);
                    }

                    @Override
                    public void onFailure(HttpException error, String msg) {
                        if (getSessionKeyCallback != null) {
                            getSessionKeyCallback.onGetSessionKeyError(msg);
                        }
                    }

                    @Override
                    public void onException() {

                    }
                }, POST);// 使用xUtils
    }

//    public static Handler mHandler;

    /**
     * 获取MD5值
     *
     * @param content 要加密的内容
     * @return 返回加密后的MD5值
     */
    public static String getVerify(String content) {
        if (content == null) {
            return "0000";
        }
        String md5Hex = DigestUtils.md5Hex(content);
        return md5Hex;
    }

    /**
     * 取得会话密钥的回调接口
     */
    public  interface onGetSessionKeyCallback {
        /**
         * 取得会话密钥时回调
         *
         * @param sessionKey
         */
        void onGetSessionKey(String sessionKey);

        /**
         * 取会话密钥错误回调
         *
         * @param msg
         */
        void onGetSessionKeyError(String msg);
    }
    /**
     * 会话密钥过期的回调接口
     */
    public interface OnExptimeCallback {
        /**
         * 当会话密钥过期时回调
         */
        void onExptimeListener();
    }

    /**
     * 设置请求参数post,put
     *
     * @param params
     * @param requestJson
     */
    private static void setParams(RequestParams params, String requestJson) {
        try {
            params.setContentType("application/json");
            StringEntity stringEntity = new StringEntity(requestJson);
            params.setBodyEntity(stringEntity);
        } catch (UnsupportedEncodingException e) {
            MyLog.e(TAG, e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 解析Json数据
     *
     * @param result               请求结果字符串
     * @param paseBaseJsonCallback 解析结果的回调接口
     * @param isCache              是否为缓存数据
     * @param cacheSessionKey      缓存的sessionKey
     */
    private static void paserBaseJson(String result, OnPaseBaseJsonCallback paseBaseJsonCallback, boolean isCache, String cacheSessionKey) {
        paserBaseJson(null,null,null,null,null,null,null,1,null,result,paseBaseJsonCallback,null,null,isCache,cacheSessionKey);
    }
    /**
     * 解析Json数据
     * @param context
     * @param url
     * @param filePath
     * @param dataMaps
     * @param rawData
     * @param dataKey
     * @param sessionKey
     * @param requestType
     * @param loadDialog
     * @param result 请求结果字符串
     * @param paseBaseJsonCallback 解析结果的回调接口
     * @param failCallback
     * @param crashExceptionCallback
     * @param isCache 是否为缓存数据
     * @param cacheSessionKey  缓存的sessionKey
     */
    private static void paserBaseJson(final Context context, final String url, final String filePath,
                                      final Map<String, Object> dataMaps, final String rawData, final String dataKey,
                                      final String sessionKey, final int requestType, final Dialog loadDialog, String result,
                                      OnPaseBaseJsonCallback paseBaseJsonCallback, final HttpFailCallback failCallback,
                                      final CrashExceptionCallback crashExceptionCallback, boolean isCache, String cacheSessionKey) {
        Gson gson = new Gson();
        BaseEntity baseEntity = null;
        try {
            MyLog.d(TAG,"返回的数据------->>>: "+result);
            baseEntity = gson.fromJson(result, BaseEntity.class);
        } catch (Exception e) {
            MyLog.e(TAG, "解析BaseEntity 错误 ！");
        }

        if (paseBaseJsonCallback == null) {
            return;
        }

        if (baseEntity == null) {
            return;
        }else{
            int requestResultCode = baseEntity.result;
            MyError mError = baseEntity.error;
            String verify = baseEntity.verify;
            String id = baseEntity.$id;
            String dataEncodeStr = baseEntity.data;
            if (requestResultCode != 1) {// 如果结果码不为1
                // 提示错误信息
                if (mError.code == 8001 ||mError.code == 8002) {
                    requestByCheckSessionkey(context,url,true,isCache,filePath,dataMaps,rawData,dataKey,sessionKey,
                            requestType,loadDialog,paseBaseJsonCallback,failCallback, crashExceptionCallback);
                    paseBaseJsonCallback.onSessionKeyInvaled();
                    MyLog.e(TAG, "请求到密钥失效----------");
                } else if(mError.code == 8002){
                    MyLog.d(TAG,"数据验证失败---这是什么失败  code: "+mError.code);
                }else{
                    paseBaseJsonCallback.onErrorCodeError(mError);
                    MyLog.e(TAG, "其它错误    code:  "+mError.code+"    msg: "+mError.msg +"    more:" +mError.more );
                }

                MyLog.e(TAG, "请求失败，result 码 ：" + requestResultCode);
            } else {
                // 1.判断是否有错误
                if (mError.code == MyHttp.NO_ERROR) {
                    // 处理正常逻辑
                    // 1.判断verify是否为空:如获取手机验证码是不要返回data的
                    if (Tools.isEmpty(verify)) {
                        // 是空，处理成功的逻辑，如提示获取验证码成功
                        paseBaseJsonCallback.onVerifyIsNull();
                        MyLog.d(TAG, "请求成功，不需要返回数据！");

                    } else {
                        // 不为空，验证MD5
                        // 1.取出Data原串
                        String dataRaw = null;
                        if (isCache) {//解密缓存数据
                            MyLog.i(TAG, "是缓存数据！");
                            dataRaw = MyHttp.getCacheDataRaw(dataEncodeStr, cacheSessionKey);
                            if (TextUtils.isEmpty(dataRaw)){
                                isCached = false ;
                            }else{
                                isCached = true ;
                            }
                        } else {
//                        MyLog.e(TAG, "加密的数据：" + dataEncodeStr);
                            dataRaw = MyHttp.getDataRaw(dataEncodeStr);
//                        MyLog.d(TAG, "服务器请求数据是  =" + dataRaw + "测试是否有空格");
                        }
                        MyLog.d(TAG, "sessionKey: " + MyApp.sessionKey + "   md5：　　" + verify);
                        // 2.Md5原串
                        String verify2 = MyHttp.getVerify(dataRaw);
                        MyLog.d(TAG, "md51 :" + verify + "      md52 :" + verify2);
                        // 3.判断
                        if (!isCache) {//不是缓存才验证MD5
                            if (verify.equals(verify2)) {
                                // 验证成功，解析数据
                                MyLog.d(TAG, "验证MD5成功,回调字符串是 ：" + dataRaw.toString());
                                paseBaseJsonCallback.onVerifySuccess(dataRaw, isCache);
                            } else {
                                // 提示错误信息

                                paseBaseJsonCallback.onVerifyError();
                                MyLog.e(TAG, "MD5验证失败！！！！！！！！！！！！！！！！");
                            }
                        } else {
                            paseBaseJsonCallback.onVerifySuccess(dataRaw, isCache);
                        }
                    }
                }
            }
        }
    }

    public static boolean getCacheData(){
        return isCached ;
    }
}
